package com.marketsim.dao;

import java.io.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Alex on 30.03.2014.
 */
public class ExchangesDAO {

    private static final String NYSE_TRADING_DAYS_FILENAME = "resources/NYSE_dates.txt";

    private List<Date> nyseTradingDays;

    private List<Date> loadNYSETradingDays() {
        List<Date> result = new ArrayList<Date>();

        try {
            InputStream inputStream = new FileInputStream(new File(NYSE_TRADING_DAYS_FILENAME));
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
            DateFormat dateFormat = new SimpleDateFormat("M/d/yyyy", Locale.ENGLISH);
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                Date date = dateFormat.parse(inputLine);
                result.add(date);
            }
        } catch (IOException | ParseException e) {
            e.printStackTrace();
        }

        return result;
    }

    public List<Date> getNYSETradingDays(Date startDate, Date endDate) {
        if (nyseTradingDays == null) {
            nyseTradingDays = loadNYSETradingDays();
        }
        if (startDate.after(endDate)) {
            throw new IllegalArgumentException();
        }
        if (startDate.after(nyseTradingDays.get(nyseTradingDays.size() - 1))) {
            throw new IllegalArgumentException();
        }

        List<Date> result = new ArrayList<>();

        int indexOfStartDate = nyseTradingDays.indexOf(startDate);
        // find startDate if it is trading day or first trading day after it
        while (indexOfStartDate == -1) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(startDate);
            cal.add(Calendar.DATE, 1);
            startDate = cal.getTime();
            indexOfStartDate = nyseTradingDays.indexOf(startDate);
        }

        int indexOfEndDate = nyseTradingDays.indexOf(endDate);
        // find startDate if it is trading day or first trading day before it
        while (indexOfStartDate == -1) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(endDate);
            cal.add(Calendar.DATE, -1);
            endDate = cal.getTime();
            indexOfStartDate = nyseTradingDays.indexOf(startDate);
        }

        return deepCopyOfList(nyseTradingDays.subList(indexOfStartDate, indexOfEndDate+1));
    }

    private List<Date> deepCopyOfList(List<Date> dates) {
        List<Date> result = new ArrayList<>(dates.size());
        for (Date date : dates) {
            result.add(date);
        }
        return result;
    }

}
